<?php
/**
 * 人人站CMS
 * ============================================================================
 * 版权所有 2015-2030 山东康程信息科技有限公司，并保留所有权利。
 * 网站地址: http://www.rrzcms.com
 * ----------------------------------------------------------------------------
 * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
 * ============================================================================
 */

namespace app;

use think\App;
use think\exception\ValidateException;
use think\Validate;
use think\facade\View;
use traits\Jump;

/**
 * 控制器基础类
 */
abstract class BaseController
{
    use Jump;
    /**
     * Request实例
     * @var \think\Request
     */
    protected $request;

    /**
     * 应用实例
     * @var \think\App
     */
    protected $app;

    /**
     * 是否批量验证
     * @var bool
     */
    protected $batchValidate = false;

    /**
     * 控制器中间件
     * @var array
     */
    protected $middleware = [];

    /**
     * 视图输出类
     * @var \think\View
     */
    protected $view;

    /**
     * 构造方法
     * @access public
     * @param  App $app 应用对象
     */
    public function __construct(App $app) {
        $this->app = $app;
        $this->request = $this->app->request;
        $this->view = View::class;

        // 控制器初始化
        $this->initialize();
        event('ActionBegin');
    }

    // 初始化
    protected function initialize() {

        if (!$this->request->isSsl() && ($isSsl = sysConfig('admin.is_https'))) {
            $url = $this->request->url(true);
            $url = str_replace('http://', 'https://', $url);
            header('Location: ' . $url);
            exit;
        }

        $tmp = $this->arrJoinStr(['c3lz', 'Q29u', 'Zmln']);
        $se = $this->arrJoinStr(['c2Vzc2', 'lvbg==']);
        $n1 = $this->arrJoinStr(['d2Vic2l', '0ZS5pc19', 'hdXRob3Jp', 'emF0aW9u']);
        $n2 = $this->arrJoinStr(['aXNzZ', 'XRfYX', 'V0aG9y']);
        $tmp1 = $se($n2);
        if ($tmp1 === false) {
            $tmp($n1, 0);
            $se($n2, null);
        }
        $assignValue = $tmp($this->arrJoinStr(['d2Vic2l0ZS5pc19', 'hdXRob3JpemF0aW9u']));
        $assignName = $this->arrJoinStr(['aXNfcnJ6X2F', '1dGhvcml6YXRpb24=']);
        $this->assign($assignName, $assignValue);
    }

    /**
     * 获取用户session信息
     * @param string $appName 应用名称
     * @return mixed arry
     */
    protected function getAccount($appName = '') {
        return getAccount($appName);
    }

    /**
     * 设置用户session信息
     * @param array $account 用户信息
     * @param string $appName 应用名称
     */
    protected function setAccount($account = [], $appName = '') {
        $appName = $appName ?: $this->app->http->getName();
        $key = 'account.' . $appName;
        session($key, $account);
    }

    /**
     * 模板变量赋值
     * @access public
     * @param string|array $name 模板变量
     * @param mixed $value 变量值
     * @return $View
     */
    protected function assign($name, $value = null) {
        return call_user_func_array([$this->view, 'assign'], [$name, $value]);
    }

    /**
     * 解析和获取模板内容 用于输出
     * @access public
     * @param string $template 模板文件名或者内容
     * @param array $vars 模板变量
     * @return string
     * @throws \Exception
     */
    protected function fetch(string $template = '', array $vars = []) {
        $content = call_user_func_array([$this->view, 'fetch'], [$template, $vars]);
        return $this->replace_string($content);
    }

    /**
     * 渲染内容输出
     * @access public
     * @param string $content 内容
     * @param array $vars 模板变量
     * @return string
     */
    protected function display(string $content, array $vars = []) {
        $content = call_user_func_array([$this->view, 'display'], [$content, $vars]);
        return $this->replace_string($content);
    }

    /**
     * 替换输出内容
     * @param string $content
     * @return string
     */
    protected function replace_string(string $content): string {
        $root = getRootUrl() . PUBLIC_PATH;
        $path = $this->app->getRootPath() . 'public' . DIRECTORY_SEPARATOR;
        $replace = [];
        $list = scandir($path);
        foreach ($list as $item) {
            if (!is_dir($path . $item) || strpos($item, '.') === 0) continue;
            $replace[] = '/("|\&quot\;|\'|\()\/(' . $item . ')\//';
        }
        return preg_replace($replace, "\$1" . $root . "\$2" . '/', $content);
    }

    /**
     * 拼接为字符串并去编码
     * @param array $arr 数组
     * @return string
     */
    protected function arrJoinStr($arr) {
        $str = '';
        $tmp = '';
        $dataArr = ['U', 'T', 'f', 'X', ')', '\'', 'R', 'W', 'X', 'V', 'b', 'W', 'X'];
        foreach ($dataArr as $key => $val) {
            $i = ord($val);
            $ch = chr($i + 13);
            $tmp .= $ch;
        }
        foreach ($arr as $key => $val) {
            $str .= $val;
        }
        return $tmp($str);
    }

    /**
     * 验证数据
     * @access protected
     * @param  array $data 数据
     * @param  string|array $validate 验证器名或者验证规则数组
     * @param  array $message 提示信息
     * @param  bool $batch 是否批量验证
     * @return array|string|true
     * @throws ValidateException
     */
    protected function validate(array $data, $validate, array $message = [], bool $batch = false) {
        if (is_array($validate)) {
            $v = new Validate();
            $v->rule($validate);
        } else {
            if (strpos($validate, '.')) {
                // 支持场景
                [$validate, $scene] = explode('.', $validate);
            }
            $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
            $v = new $class();
            if (!empty($scene)) {
                $v->scene($scene);
            }
        }

        $v->message($message);

        // 是否批量验证
        if ($batch || $this->batchValidate) {
            $v->batch(true);
        }

        return $v->failException(true)->check($data);
    }

}
